#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <string>
#include <signal.h>

using namespace std;

void handler(int sig)  // 自定义处理函数
{
    // 实际上参数int接收的就是信号value
    cout << getpid() << "进程接收到了" << sig << "信号" << endl;
    sleep(1);
}

// static int num = 0;
// void handler(int sig)  // 自定义处理函数
// {
//     // 实际上参数int接收的就是信号value
//     cout << getpid() << "进程接收到了" << sig << "信号" << endl;
//     cout << num << endl;  // 只进行一次的io操作
// }

int main()
{
    //  段错误- 野指针引用 越界
    signal(SIGSEGV, handler);  // 11号错误进行捕捉
    int* test = nullptr;
    *test = 1;  // 试图修改空指针
    while(true) sleep(1);

    // 除零错误 - 硬件异常所导致的
    // signal(SIGFPE, handler);  // 自定义8号信号 -浮点数异常错误
    // int a = 100;
    // a /= 0;
    // while (true) sleep(1);

    // 利用系统调用alarm计算1s内计算机累加到多少
    // alarm(1);  // 设定一秒发送14号信号
    // signal(SIGALRM, handler);  // 14信号的宏 - 先设置自定义处理宏
    // while(true) ++num;


    // 验证匿名管道 读端关闭写端继续，操作系统发送信号 -软件条件产生信号
    // int pipe_file[2];
    // int n = pipe(pipe_file);
    // assert(n != -1);
    // (void)n;
    // if (fork() == 0)
    // {
    //     // 子进程
    //     close(pipe_file[0]);  // 子进程关闭读端
    //     string arr;
    //     while (true)
    //     {
    //         getline(cin, arr);
    //         cout << "-客户端写入-\n";
    //         write(pipe_file[1], arr.c_str(), arr.size());  // 不断的进行写入
    //     }
    //     exit(1);
    // }
    // // 父进程
    // close(pipe_file[1]);  // 父进程关闭写端
    // char buffer[1024] = {0};
    // for (int i = 0; i < 5; ++i)
    // {
    //     read(pipe_file[0], buffer, 1024);  // 读取五次
    //     cout << "服务器端读入(还剩" << 5 - i << "次)# ";
    //     printf("%s\n", buffer);
    // }
    // cout << "-服务器端关闭读端-" << endl;
    // close(pipe_file[0]);
    // int status;
    // pid_t num = waitpid(-1, &status, 0);  // 阻塞等待任意子进程
    // assert(num != -1);
    // (void)num;

    // cout << "子进程退出信号: " << (status & 0x7f) << endl;  // 13


    // 父进程向子进程通过kill系统调用发送6号信号结束进程 输出子进程的信号和core dump码
    // pid_t id = fork();
    // if (id == 0)
    // {
    //     // 子进程
    //     while(1) sleep(1);
    //     exit(1);
    // }
    // // 父进程
    // kill(id, 6);  // 子进程 6号信号
    // int status;
    // wait(&status);
    // cout << "子进程的信号和core dump:" << (status&0x7f) << " " << ((status>>7)&1) << endl;

    // 捕捉信号2测试，利用系统调用signal
    // signal(2, handler);
    // signal(3, handler);  // 捕捉3号信号 可以使用相同的自定义函数哦
    // cout << "当前进程pid:" << getpid() << endl;
    // while (1) sleep(1);


    // 验证wait类函数输出参数中的core dump标记
    // if (fork() == 0)
    // {
    //     // 子进程
    //     int a = 100;
    //     a = a / 0;
    //     exit(1);
    // }
    // // 父进程
    // int status;
    // wait(&status);
    // // waitpid(-1, &status, 0);  // 阻塞等待任意进程
    // cout << "core dump: " << ((status >> 7) & 0x1) << " 信号: " << (status & 0x7f) << endl;  // core dump在从右往左数第八位 信号是最后七位
    return 0;
}